home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / mutils.asm < prev    next >
Encoding:
Assembly Source File  |  1997-01-16  |  12.0 KB  |  552 lines

  1. ;*    MUTILS.ASM
  2. ;*
  3. ;* Miscellaneous utility functions for MIDAS Sound System used
  4. ;* by various system components.
  5. ;*
  6. ;* $Id: mutils.asm,v 1.4 1997/01/16 18:41:59 pekangas Exp $
  7. ;*
  8. ;* Copyright 1996,1997 Housemarque Inc.
  9. ;*
  10. ;* This file is part of the MIDAS Sound System, and may only be
  11. ;* used, modified and distributed under the terms of the MIDAS
  12. ;* Sound System license, LICENSE.TXT. By continuing to use,
  13. ;* modify or distribute this file you indicate that you have
  14. ;* read the license and understand and accept it fully.
  15. ;*
  16.  
  17. ; Possibly environment dependent code is marked with *!!*
  18.  
  19.  
  20.  
  21. IDEAL
  22. P386
  23.  
  24. INCLUDE "lang.inc"
  25. INCLUDE "mutils.inc"
  26.  
  27.  
  28. DATASEG
  29.  
  30. IFDEF __WC32__
  31. EXTRN   _psp : word
  32. ENDIF
  33.  
  34.  
  35. CODESEG
  36.  
  37.  
  38. ;/***************************************************************************\
  39. ;*
  40. ;* Function:     int mGetKey(void)
  41. ;*
  42. ;* Description:  Waits for a keypress and returns the read key
  43. ;*
  44. ;* Returns:     ASCII code for the key pressed. Extended keycodes are
  45. ;*         returned with bit 8 set, eg. up arrow becomes \x148.
  46. ;*
  47. ;\***************************************************************************/
  48.  
  49. PROC    mGetKey         _funct
  50. USES    _bx
  51.  
  52.         ;*!!*
  53.  
  54. IFDEF __32__
  55.         xor     eax,eax
  56. ENDIF
  57.  
  58.     mov    ax,0700h        ; read key without echo
  59.     int    21h
  60.  
  61.     xor    ah,ah
  62.     test    al,al            ; read key zero?
  63.     jnz    @@keyok         ; if not, it is the key ASCII code
  64.  
  65.     ; the read key was zero - now read the actual extended keycode and
  66.     ; return it with bit 8 set.
  67.  
  68.     mov    ax,0700h        ; read key without echo
  69.     int    21h
  70.     mov    ah,1            ; set bit 8 to 1
  71.  
  72. @@keyok:
  73.     ret
  74. ENDP
  75.  
  76.  
  77.  
  78.  
  79. ;/***************************************************************************\
  80. ;*
  81. ;* Function:     int mStrLength(char *str)
  82. ;*
  83. ;* Description:  Calculates the length of a ASCIIZ string
  84. ;*
  85. ;* Input:     char *str         pointer to string
  86. ;*
  87. ;* Returns:     String length excluding the terminating '\0'.
  88. ;*
  89. ;\***************************************************************************/
  90.  
  91. PROC    mStrLength      _funct  str : _ptr
  92. USES    _bx
  93.  
  94. IFDEF __32__
  95.         mov     ax,ds
  96.         mov     es,ax
  97. ENDIF
  98.  
  99.         LOADPTR es,_bx,[str]            ; point es:bx to string
  100.         xor     _ax,_ax                 ; current length = 0
  101.  
  102. @@lp:
  103.         cmp     [byte _esbx],0          ; is current byte 0
  104.     je    @@done            ; if is, we are finished
  105.         inc     _bx                     ; next byte
  106.         inc     _ax
  107.     jmp    @@lp
  108.  
  109. @@done:
  110.     ret
  111. ENDP
  112.  
  113.  
  114.  
  115.  
  116. ;/***************************************************************************\
  117. ;*
  118. ;* Function:     void mStrCopy(char *dest, char *src);
  119. ;*
  120. ;* Description:  Copies an ASCIIZ string from *src to *dest.
  121. ;*
  122. ;* Input:     char *dest         pointer to destination string
  123. ;*         char *src         pointer to source string
  124. ;*
  125. ;\***************************************************************************/
  126.  
  127. PROC    mStrCopy        _funct  dest : _ptr, src : _ptr
  128. USES    _si,_di
  129.  
  130.         PUSHSEGREG ds
  131.  
  132.     ; Clear enough as it is? If not, maybe you shouldn't be reading
  133.     ; this source after all...
  134.  
  135. IFDEF __32__
  136.         mov     ax,ds
  137.         mov     es,ax
  138. ENDIF
  139.  
  140.     cld
  141.         LOADPTR ds,_si,[src]
  142.         LOADPTR es,_di,[dest]
  143.  
  144. @@lp:    lodsb
  145.     stosb
  146.     test    al,al
  147.     jnz    @@lp
  148.  
  149. @@done:
  150.         POPSEGREG ds
  151.  
  152.     ret
  153. ENDP
  154.  
  155.  
  156.  
  157.  
  158. ;/***************************************************************************\
  159. ;*
  160. ;* Function:     void mStrAppend(char *dest, char *src);
  161. ;*
  162. ;* Description:  Appends an ASCIIZ string to the end of another.
  163. ;*
  164. ;* Input:     char *dest         pointer to destination string
  165. ;*         char *src         pointer to source string
  166. ;*
  167. ;\***************************************************************************/
  168.  
  169. PROC    mStrAppend      _funct  dest : _ptr, src : _ptr
  170. USES    _si,_di
  171.  
  172.     ; Again, if you don't understand this you should perhaps consider
  173.     ; switching hobby...
  174.  
  175.         PUSHSEGREG ds
  176.  
  177. IFDEF __32__
  178.         mov     ax,ds
  179.         mov     es,ax
  180. ENDIF
  181.  
  182.     cld
  183.         LOADPTR ds,_si,[src]
  184.         LOADPTR es,_di,[dest]
  185.  
  186. @@l1:   mov     al,[_esdi]
  187.     test    al,al
  188.     jz    @@lp
  189.         inc     _di
  190.     jmp    @@l1
  191.  
  192. @@lp:    lodsb
  193.     stosb
  194.     test    al,al
  195.         jz      @@done
  196.     jmp    @@lp
  197.  
  198. @@done:
  199.         POPSEGREG ds
  200.  
  201.     ret
  202. ENDP
  203.  
  204.  
  205.  
  206. ;/***************************************************************************\
  207. ;*
  208. ;* Function:     void mMemCopy(char *dest, char *src, unsigned numBytes);
  209. ;*
  210. ;* Description:  Copies a memory block from *src to *dest.
  211. ;*
  212. ;* Input:     char *dest         pointer to destination
  213. ;*         char *src         pointer to source
  214. ;*         unsigned numBytes     number of bytes to copy
  215. ;*
  216. ;\***************************************************************************/
  217.  
  218. PROC    mMemCopy        _funct  dest : _ptr, src : _ptr, numBytes : _int
  219. USES    _si,_di
  220.  
  221. IFDEF __32__
  222.         mov     ax,ds
  223.         mov     es,ax
  224. ENDIF
  225.  
  226.         PUSHSEGREG ds
  227.  
  228.     cld
  229.         LOADPTR ds,_si,[src]
  230.         LOADPTR es,_di,[dest]
  231.         mov     _cx,[numBytes]
  232.     rep    movsb
  233.  
  234.         POPSEGREG ds
  235.  
  236.     ret
  237. ENDP
  238.  
  239.  
  240.  
  241.  
  242. ;/***************************************************************************\
  243. ;*
  244. ;* Function:     int mMemEqual(char *m1, char *m2, unsigned numBytes);
  245. ;*
  246. ;* Description:  Compares two memory blocks.
  247. ;*
  248. ;* Input:     char *m1         pointer to memory block #1
  249. ;*         char *m2         pointer to memory block #2
  250. ;*         unsigned numBytes     number of bytes to compare
  251. ;*
  252. ;* Returns:     1 if the memory blocks are equal, 0 if not.
  253. ;*
  254. ;\***************************************************************************/
  255.  
  256. PROC    mMemEqual       _funct  m1 : _ptr, m2 : _ptr, numBytes : _int
  257. USES    _si,_di
  258.  
  259. IFDEF __32__
  260.         mov     ax,ds
  261.         mov     es,ax
  262. ENDIF
  263.  
  264.         PUSHSEGREG ds
  265.  
  266.     cld
  267.         LOADPTR ds,_si,[m1]
  268.         LOADPTR es,_di,[m2]
  269.         mov     _cx,[numBytes]
  270.     repe    cmpsb
  271.         test    _cx,_cx
  272.     jnz    @@une
  273.         mov     _ax,1
  274.     jmp    @@done
  275.  
  276. @@une:  xor     _ax,_ax
  277.  
  278. @@done:
  279.         POPSEGREG ds
  280.  
  281.     ret
  282. ENDP
  283.  
  284.  
  285.  
  286.  
  287. ;/***************************************************************************\
  288. ;*
  289. ;* Function:     long mHex2Long(char *hex)
  290. ;*
  291. ;* Description:  Converts a hexadecimal string to a long integer.
  292. ;*
  293. ;* Input:     char *hex         pointer to hex string, ASCIIZ
  294. ;*
  295. ;* Returns:     Value of the string or -1 if conversion failure.
  296. ;*
  297. ;\***************************************************************************/
  298.  
  299. PROC    mHex2Long       _funct  hex : _ptr
  300. USES    _bx
  301.  
  302.         LOADPTR es,_bx,[hex]            ; point es:bx to string
  303.     xor    edx,edx         ; current number is zero
  304.  
  305. @@lp:   mov     al,[_esbx]              ; get character from string
  306.         inc     _bx
  307.     test    al,al            ; terminating '\0'?
  308.     jz    @@strend
  309.  
  310.     shl    edx,4            ; move previous string data to left
  311.  
  312.     cmp    al,'0'                  ; character below '0'?
  313.     jb    @@err            ; if yes, error
  314.     cmp    al,'9'                  ; character <= '9'?
  315.     jbe    @@decdigit        ; if yes, it's a decimal digit
  316.  
  317.     cmp    al,'A'                  ; character below 'A'?
  318.     jb    @@err            ; if yes, error
  319.     cmp    al,'F'                  ; character <= 'F'?
  320.     jbe    @@chexdigit        ; if yes, it's a capital hex digit
  321.  
  322.     cmp    al,'a'                  ; character below 'a'?
  323.     jb    @@err            ; if yes, error
  324.     cmp    al,'f'                  ; character <= 'f'?
  325.     jbe    @@shexdigit        ; if yes, it's a small hex digit
  326.  
  327.     jmp    @@err            ; unrecognized character - error
  328.  
  329. @@decdigit:
  330.     sub    al,'0'                  ; al = current digit value
  331.     or    dl,al            ; add it to edx
  332.     jmp    @@lp            ; and get next character
  333.  
  334. @@chexdigit:
  335.     sub    al,'A'-0Ah              ; al = current digit value
  336.     or    dl,al            ; add it to edx
  337.     jmp    @@lp            ; and get next character
  338.  
  339. @@shexdigit:
  340.     sub    al,'a'-0Ah              ; al = current digit value
  341.     or    dl,al            ; add it to edx
  342.     jmp    @@lp            ; and get next character
  343.  
  344. @@strend:
  345. IFDEF __16__
  346.     mov    ax,dx            ; move result from edx to dx:ax
  347.     shr    edx,16
  348. ELSE
  349.         mov     eax,edx
  350. ENDIF
  351.     jmp    @@done            ; and leave
  352.  
  353. @@err:
  354. IFDEF __16__
  355.         mov     ax,-1
  356.     mov    dx,-1
  357. ELSE
  358.         mov     _ax,-1
  359. ENDIF
  360.  
  361. @@done:
  362.     ret
  363. ENDP
  364.  
  365.  
  366.  
  367.  
  368. ;/***************************************************************************\
  369. ;*
  370. ;* Function:     long mDec2Long(char *dec)
  371. ;*
  372. ;* Description:  Converts an unsigned decimal string to a long integer
  373. ;*
  374. ;* Input:     char *dec         pointer to string, ASCIIZ
  375. ;*
  376. ;* Returns:     Value of the string or -1 if conversion failure.
  377. ;*
  378. ;\***************************************************************************/
  379.  
  380. PROC    mDec2Long       _funct  dec : _ptr
  381. USES    _bx
  382.  
  383.         LOADPTR es,_bx,[dec]            ; point es:bx to string
  384.     xor    edx,edx         ; current value is zero
  385.         xor     eax,eax
  386.  
  387. @@lp:
  388.         mov     al,[_esbx]              ; get character from string
  389.     inc    bx
  390.     test    al,al            ; terminating '\0'?
  391.     jz    @@strend
  392.  
  393.     imul    edx,edx,10        ; multiply current value by 10 to
  394.                     ; make room for the new digit
  395.     cmp    al,'0'                  ; character below '0'?
  396.     jb    @@err            ; if yes, error
  397.     cmp    al,'9'                  ; character above '9'?
  398.     ja    @@err            ; if yes, error
  399.  
  400.     sub    al,'0'                  ; al = current digit value
  401.         add     edx,eax                 ; add it to edx
  402.     jmp    @@lp            ; and get next character
  403.  
  404. @@strend:
  405. IFDEF __16__
  406.     mov    ax,dx            ; move result from edx to dx:ax
  407.     shr    edx,16
  408. ELSE
  409.         mov     eax,edx
  410. ENDIF
  411.  
  412.     jmp    @@done            ; and leave
  413.  
  414. @@err:
  415. IFDEF __16__
  416.     mov    ax,-1
  417.     mov    dx,-1
  418. ELSE
  419.         mov     eax,-1
  420. ENDIF
  421.  
  422. @@done:
  423.     ret
  424. ENDP
  425.  
  426.  
  427.  
  428.  
  429. ;/**************************************************************************\
  430. ;*
  431. ;* Function:     char *mGetEnv(char *envVar);
  432. ;*
  433. ;* Description:  Searches a string from the environment
  434. ;*
  435. ;* Input:     envVar          environment variable name, ASCIIZ
  436. ;*
  437. ;* Returns:     Pointer to environment string value (ASCIIZ), NULL if string
  438. ;*         was not found.
  439. ;*
  440. ;\**************************************************************************/
  441.  
  442. PROC    mGetEnv         _funct  envVar : _ptr
  443. USES    _si,_di,_bx
  444.  
  445.         ;*!!*
  446.  
  447.         PUSHSEGREG ds
  448. IFDEF __32__
  449.         push    es
  450.         mov     ax,ds
  451.         mov     es,ax
  452. ENDIF
  453.  
  454.         cld
  455.         LOADPTR es,_di,[envVar]         ; point es:di and es:bx to environment
  456.         mov     _bx,_di                 ; variable name
  457.     xor    al,al
  458.     mov    cx,7FFFh
  459.     repne    scasb            ; scan for first 0 in string
  460.         sub     _di,_bx
  461.         dec     _di
  462.         mov     _dx,_di                 ; dx = string length (excl. '\0')
  463.  
  464.         test    _dx,_dx                 ; skip if zero length string
  465.     jz    @@notfound
  466.  
  467. IFDEF __WC32__
  468.         mov     bx,[_psp]
  469. ELSE
  470.     mov    ah,62h            ; int 21h, function 62h - get PSP seg
  471.     int    21h            ; bx = PSP segment
  472. ENDIF
  473.  
  474.         LOADPTR ds,_si,[envVar]         ; point ds:si to variable name
  475.     mov    es,bx            ; es = PSP segment
  476.         mov     es,[es:2Ch]             ; es = Environment segment
  477.         xor     _di,_di                 ; point es:di to environment
  478.  
  479.         mov     ah,[_si]                ; ah = first character of string
  480.     xor    al,al            ; al = 0 !!!
  481.  
  482. @@search:
  483.         cmp     [es:_di],ah             ; Is the first letter of the current
  484.     jne    @@skipend        ; environment string same as the one
  485.                     ; we are looking for? If not, skip
  486.                     ; the whole string.
  487.  
  488.         push    _si
  489.         mov     _cx,_dx
  490.     repe    cmpsb            ; check if the whole string is equal
  491.         pop     _si
  492.     jne    @@skipend        ; skip if not
  493.         cmp     [byte es:_di],"="       ; check is the next character is '='
  494.     jne    @@skipend        ; skip if not
  495.         inc     _di                     ; point es:di to start of environment
  496. IFDEF __16__
  497.     mov    dx,es            ; return pointer in dx:ax
  498.     mov    ax,di
  499. ELSE
  500.  
  501.         mov     eax,0006h               ; DPMI function 7 - get segment base
  502.         xor     ebx,ebx
  503.         mov     bx,es
  504.         int     31h
  505.         jc      @@notfound
  506.  
  507.         mov     eax,ecx                 ; eax = environment selector base
  508.         shl     eax,16                  ; address
  509.         mov     ax,dx
  510.         add     eax,edi
  511. ENDIF
  512.     jmp    @@done
  513.  
  514. @@skipend:
  515.         mov     _cx,7FFFh
  516.     repne    scasb            ; search for first '\0'.
  517.         cmp     [byte es:_di],0         ; is the next byte also 0?
  518.     je    @@notfound        ; if is, end of environment
  519.     jmp    @@search
  520.  
  521. @@notfound:
  522.         xor     _ax,_ax                 ; string was not found - return NULL
  523. IFDEF __16__
  524.     xor    dx,dx
  525. ENDIF
  526.  
  527. @@done:
  528. IFDEF __32__
  529.         pop     es
  530. ENDIF
  531.         POPSEGREG ds
  532.  
  533.     ret
  534. ENDP
  535.  
  536.  
  537. ;* $Log: mutils.asm,v $
  538. ;* Revision 1.4  1997/01/16 18:41:59  pekangas
  539. ;* Changed copyright messages to Housemarque
  540. ;*
  541. ;* Revision 1.3  1996/08/04 11:31:14  pekangas
  542. ;* All routines now preserve _ebx
  543. ;*
  544. ;* Revision 1.2  1996/07/13 17:28:46  pekangas
  545. ;* All routines now preserve ebx
  546. ;*
  547. ;* Revision 1.1  1996/05/22 20:49:33  pekangas
  548. ;* Initial revision
  549. ;*
  550.  
  551.  
  552. END